# -*- coding: UTF-8 -*-

from config import config
from lib.usercookie import usercookie
from lib.gtwtools import gtwtools

import logging
import re
from urllib import quote, urlencode
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template

from django.utils import simplejson as json

class AjaxAPI(webapp.RequestHandler):
    def get(self):
        process(self, method='get')
    def post(self):
        process(self, method='post')

def process(handler, method):
    request = handler.request
    response = handler.response;
    response.headers['Content-Type'] = 'text/javascript; charset=utf-8'
    #method = m
    
    tokens = None
    if config.cookie_name in request.cookies:
        tokens = usercookie.decrypt(request.cookies[config.cookie_name])

    if tokens is None:
        #response.headers['Location'] = '/login/'
        #response.set_status(302)
        return
    
    do = request.get('do')  
    action_maps = {
        'timeline': timeline,
        'update': update,
        'retweet': retweet,
        'destroy': destroy,
        'favorite': favorite
    }

    if do in action_maps:
        action_maps.get(do)(handler, tokens)
    
    return

def favorite(handler, tokens):
    request = handler.request
    response = handler.response
    
    id = request.get('id')
    action = request.get('action')
    
    data = {}
    
    url = config.api + 'favorites/' + action + '/' + id +'.' + config.format
    params = gtwtools.get_oauth_params(base_url = url, 
                                       params = {'oauth_token': tokens['oauth_token']}, 
                                       token_secret = tokens['oauth_token_secret'], 
                                       method = 'POST')
    result = gtwtools.get_json(url=url, body=urlencode(data), headers={'Authorization': 'OAuth ' + gtwtools.dict2qscomma(params)}, method='POST')
    
    if result is None:
        #response.out.write('Update Status Error')
        logging.error('favorites result error: %s \n message: %s \n params: %s' % (result, id, params))
        return
    response.out.write(json.dumps(result))
    
    return

def retweet(handler, tokens):
    request = handler.request
    response = handler.response
    
    id = request.get('id')
    
    data = {}
    
    url = config.api + 'statuses/retweet/' + id +'.' + config.format
    params = gtwtools.get_oauth_params(base_url = url, 
                                       params = {'oauth_token': tokens['oauth_token']}, 
                                       token_secret = tokens['oauth_token_secret'], 
                                       method = 'POST')
    result = gtwtools.get_json(url=url, body=urlencode(data), headers={'Authorization': 'OAuth ' + gtwtools.dict2qscomma(params)}, method='POST')
    
    if result is None:
        #response.out.write('Update Status Error')
        logging.error('retweet result error: %s \n message: %s \n params: %s' % (result, id, params))
        return
    response.out.write(json.dumps(result))
    
    return

def destroy(handler, tokens):
    request = handler.request
    response = handler.response
    
    id = request.get('id')
    
    data = {}
    
    url = config.api + 'statuses/destroy/' + id +'.' + config.format
    params = gtwtools.get_oauth_params(base_url = url, 
                                       params = {'oauth_token': tokens['oauth_token']}, 
                                       token_secret = tokens['oauth_token_secret'], 
                                       method = 'POST')
    result = gtwtools.get_json(url=url, body=urlencode(data), headers={'Authorization': 'OAuth ' + gtwtools.dict2qscomma(params)}, method='POST')
    
    if result is None:
        #response.out.write('Update Status Error')
        logging.error('destroy result error: %s \n message: %s \n params: %s' % (result, id, params))
        return
    response.out.write(json.dumps(result))
    
    return

def update(handler, tokens):
    request = handler.request
    response = handler.response
    
    status = request.get('status')
    reply_to = request.get('reply_to')
    
    # TODO: message length limit: 140
    data = {'status': status.encode('UTF-8')}
    data_params = {'status': quote(status.encode('UTF-8'), '~')}
    if reply_to != '':
        data['in_reply_to_status_id'] = reply_to
        data_params['in_reply_to_status_id'] = reply_to
    
    url = config.api + 'statuses/update.' + config.format
    params = gtwtools.get_oauth_params(base_url = url, 
                                       params = {'oauth_token': tokens['oauth_token']}, 
                                       temp_params = data_params, 
                                       token_secret = tokens['oauth_token_secret'], 
                                       method = 'POST')
    result = gtwtools.get_json(url=url, body=urlencode(data), headers={'Authorization': 'OAuth ' + gtwtools.dict2qscomma(params)}, method='POST')
    
    if result is None:
        #response.out.write('Update Status Error')
        logging.error('update result error: %s \n message: %s \n params: %s' % (result, status, params))
        return
    response.out.write(json.dumps(result))
    return

def timeline(handler, tokens):
    request = handler.request
    response = handler.response
    
    tpl = config.tpl_path + 'api/home_timeline.html'
    
    since_id = request.get('since_id')
    page = request.get('page')
    screen_name = request.get('screen_name')
    
    # fetch home timeline
    url = config.api + 'statuses/home_timeline.' + config.format
    data_params = {}
    if since_id != '' and since_id != '0':
        data_params['since_id'] = since_id
    elif page != '':
        data_params['page'] = page
        data_params['count'] = config.pagesize
    
    if screen_name != '':
        data_params['screen_name'] = screen_name
        url = config.api + 'statuses/user_timeline.' + config.format
    
    qs = False
    url_params = {}
    for key in data_params:
        qs = True
        url_params[key] = data_params[key]

    # parameters not included in base_url
    params = gtwtools.get_oauth_params(base_url = url, params = {'oauth_token': tokens['oauth_token']}, temp_params = data_params, token_secret = tokens['oauth_token_secret'], method = 'GET')
        
    if qs:
        url = url + '?' + gtwtools.dict2qs(url_params)
    tweets = gtwtools.get_json(url=url, headers={'Authorization': 'OAuth ' + gtwtools.dict2qscomma(params)}, method='GET')
    
    if tweets is None:
        logging.error('get tweets error: %s' % (url))
        return
    
    mention = re.compile(r'(@([\w_]+))', re.I|re.M)
    link = re.compile(r'(https?://[-\w]+\./?[-_\./\?%&=#\w]*)', re.I|re.M)
    status = ''
    for tweet in tweets:
        if tweet is None:
            continue        
        #tweet['time_text'] = gtwtools.semantic_time(tweet['created_at'], '%a %b %d %H:%M:%S +0000 %Y')
        status = tweet['text']
        status = mention.sub(u'<a href="/\\2" title="\\1">\\1</a>', status)
        status = link.sub(u'<a href="\\1" target="_blank" title="">\\1</a>', status)
        tweet['text'] = status
    
    max_id = 0
    since_id = 0
    count = len(tweets)
    
    if count > 0:
        since_id = tweets[0]['id']
        max_id = tweets[count - 1]['id']
    
    user = {'screen_name': tokens['screen_name']}
    data = template.render(tpl, {'user': user, 'tweets': tweets}).decode('utf-8')
    data = re.sub('^[^<]+', '', data)
    data = re.sub('\'', '\\\'', data)
    data = re.sub('\s*[\r\n]+\s*', ' ', data)
    response.out.write("{'since_id': %s, 'max_id': %s ,'html': '%s'}" % (since_id, max_id, data))
    
    return